<template>
    <div class="interview-voice">
        <!-- 面试时长 -->
        <div class="interview-timer">
            <span>{{ formatTime(duration) }}</span>
        </div>

        <!-- 顶部提示 -->
        <div class="top-tip" v-if="showTip">
            <van-notice-bar left-icon="volume-o" :scrollable="false" text="面试即将结束，时长不足5分钟无法查看面试结果">
            </van-notice-bar>
        </div>

        <!-- AI头像区域 -->
        <div class="ai-avatar">
            <div class="avatar-bg">
                <img src="/images/mine/ai-avatar.png" alt="AI面试官">
            </div>
            <!-- 语音状态文本 -->
            <div class="voice-status">
                <template v-if="!isUserSpeaking">
                    <span v-if="aiSpeaking">正在说话...</span>
                    <span v-else>等待你说话...</span>
                </template>
                <!-- 波形动画 -->
                <div v-else class="wave-animation">
                    <span v-for="i in 4" :key="i" class="wave-bar" :style="{ animationDelay: `${i * 0.1}s` }"></span>
                </div>
            </div>
        </div>

        <!-- 语音提示 -->
        <div class="voice-tip" v-if="showVoiceTip">
            <van-icon name="volume-o" />
            <span>请允许浏览器使用麦克风</span>
        </div>

        <!-- 底部控制栏 -->
        <div class="control-bar">
            <!-- 静音按钮 -->
            <div class="control-btn" :class="{ active: isMuted }" @click="toggleMute">
                <img :src="isMuted ? '/images/interview/volume-o.png' : '/images/interview/volume.png'" />
                <span>{{ isMuted ? '你已静音' : '静音' }}</span>
            </div>

            <!-- 打断按钮 -->
            <div class="interrupt-btn" @click="handleInterrupt" :class="{ disabled: !aiSpeaking }">
                <van-icon name="stop-circle-o" />
                <!-- 等待AI回答 -->
                <span>{{ aiSpeaking ? '停止播放' : '' }}</span>
            </div>

            <!-- 挂断按钮 -->
            <div class="control-btn hang-up" @click="showEndConfirm">
                <img src="/images/interview/close.png" />
                <span>挂断</span>
            </div>
        </div>

        <!-- 结束确认弹窗 -->
        <van-dialog v-model:show="showEndDialog" :title="duration < 300 ? '是否要提前结束面试？' : '结束面试'"
            :message="getEndDialogMessage()" show-cancel-button cancel-button-text="继续面试" confirm-button-text="结束面试"
            @confirm="handleHangUp" />
        <audio id="ttsPlayer" controls></audio>
    </div>
</template>

<script setup>
    import { useRouter, useRoute } from 'vue-router'
    import { showToast, showDialog } from 'vant'
    import { interviewApi, interviewUrl } from '@/api/interview'
    import { useInterviewStore } from '@/store/modules/interview'

    const router = useRouter()
    const route = useRoute()
    const duration = ref(0)
    const isMuted = ref(false)
    const isUserSpeaking = ref(false)
    const aiSpeaking = ref(false)
    const showTip = ref(false)
    const showVoiceTip = ref(true)
    const showEndDialog = ref(false)
    const isAudioPlaying = ref(false)
    const ttsPlayer = ref(null)
    const interviewRecordId = ref('')
    const interviewStore = useInterviewStore()
    let hasInterviewed = ref(null)

    // 音频相关变量
    let ws = null
    let audioContext = null
    let input = null
    let processor = null
    let accumulatedData = []
    const sampleRate = 16000
    const bufferSize = 4096
    let timer = null
    let sendInterval = null

    // 初始化音频和WebSocket
    const initAudioAndWS = async () => {
        try {
            // 1. 获取音频设备权限
            const stream = await navigator.mediaDevices.getUserMedia({
                audio: {
                    channelCount: 1,           // 单声道
                    sampleRate: sampleRate,    // 采样率16000Hz
                    echoCancellation: true,    // 开启回声消除
                    noiseSuppression: true     // 开启降噪
                }
            })

            // 设置音频处理
            audioContext = new AudioContext({
                sampleRate: sampleRate,
                latencyHint: 'interactive'
            })

            input = audioContext.createMediaStreamSource(stream)
            processor = audioContext.createScriptProcessor(bufferSize, 1, 1)

            input.connect(processor)
            processor.connect(audioContext.destination)

            // 处理音频数据
            processor.onaudioprocess = (e) => {
                if (ws && ws.readyState === WebSocket.OPEN && !isAudioPlaying.value) {
                    const inputData = e.inputBuffer.getChannelData(0)
                    const pcmData = new Int16Array(inputData.length)
                    for (let i = 0; i < inputData.length; i++) {
                        pcmData[i] = Math.max(-32768, Math.min(32767, inputData[i] * 0x7FFF))
                    }
                    accumulatedData.push(...pcmData)
                }
            }

            // 2. 连接WebSocket
            const token = localStorage.getItem('token')
            ws = new WebSocket(interviewUrl + token)

            ws.onopen = function () {
                console.log('连接成功')
                ws.send(JSON.stringify({
                    operation_type: 'start',
                    interview_id: interviewRecordId.value
                }))

                // 开始定时发送音频数据
                sendInterval = setInterval(() => {
                    if (ws && ws.readyState === WebSocket.OPEN && !isAudioPlaying.value && accumulatedData.length > 0) {
                        const dataToSend = accumulatedData.slice(0, sampleRate)
                        ws.send(new Int16Array(dataToSend).buffer)
                        accumulatedData = accumulatedData.slice(Math.min(sampleRate, accumulatedData.length))
                        console.log("发送1秒音频数据")
                    }
                }, 1000)
            }

            ws.onmessage = function (e) {
                console.log('收到消息：', e.data)
                const data = JSON.parse(e.data)
                if (data.code === 0 && data.data && data.data.question_url) {
                    aiSpeaking.value = true
                    isUserSpeaking.value = false
                    const audio = document.getElementById('ttsPlayer')
                    audio.src = data.data.question_url
                    audio.play()
                    isAudioPlaying.value = true
                }

                if (data.data?.available_seconds !== undefined) {
                    duration.value = data.data.available_seconds
                    if (duration.value <= 30) {
                        showTip.value = true
                    }
                }
            }

            ws.onclose = function () {
                console.log('连接关闭')
                clearInterval(sendInterval)
            }

            ws.onerror = function () {
                console.log('连接出错')
            }

            showVoiceTip.value = false
        } catch (error) {
            console.error('初始化失败:', error)
            showToast('获取麦克风权限失败')
        }
    }

    // 清理资源
    const cleanup = () => {
        if (sendInterval) {
            clearInterval(sendInterval)
            sendInterval = null
        }

        if (ws) {
            try {
                ws.send(JSON.stringify({
                    operation_type: 'stop',
                    interview_id: interviewRecordId.value
                }))
            } catch (error) {
                console.error('发送结束消息失败:', error)
            }
            ws.close()
            ws = null
        }

        if (processor) {
            processor.disconnect()
            processor = null
        }

        if (input) {
            input.disconnect()
            input = null
        }

        if (audioContext) {
            audioContext.close()
            audioContext = null
        }

        if (timer) {
            clearInterval(timer)
            timer = null
        }

        accumulatedData = []
        isAudioPlaying.value = false
    }

    // 处理打断
    const handleInterrupt = () => {
        if (aiSpeaking.value) {
            const audio = document.getElementById('ttsPlayer')
            audio.pause()
            aiSpeaking.value = false
            isAudioPlaying.value = false
            isUserSpeaking.value = false
        }
    }

    // 切换静音
    const toggleMute = () => {
        isMuted.value = !isMuted.value
        const audio = document.getElementById('ttsPlayer')
        audio.muted = isMuted.value
    }

    // 格式化时间
    const formatTime = (seconds) => {
        // 确保秒数不为负
        const totalSeconds = Math.max(0, seconds)
        const minutes = Math.floor(totalSeconds / 60)
        const remainingSeconds = totalSeconds % 60
        return `${String(minutes).padStart(2, '0')}:${String(remainingSeconds).padStart(2, '0')}`
    }

    // 获取结束对话框的消息
    const getEndDialogMessage = () => {
        console.log(hasInterviewed.value)
        if (!hasInterviewed.value && duration.value < 300) { // 5分钟
            return '面试体验机会仅有一次，结束后将无法再次免费体验，可以选择继续面试，或者结束面试'
        }
        return '确定要结束本次面试吗？'
    }

    // 显示结束确认
    const showEndConfirm = () => {
        showEndDialog.value = true
    }

    // 处理挂断
    const handleHangUp = () => {
        if (duration.value >= 1800) {
            router.push({
                path: '/profile/interviews/detail',
                query: {
                    interview_record_id: interviewRecordId.value
                }
            }) // 正常结束去结果页
        } else {
            router.push('/home') // 提前结束回到首页
            // if (duration.value < 300) { // 5分钟
        }
    }

    onMounted(async () => {
        interviewRecordId.value = route.query.interview_record_id

        // 启动本地计时器作为备份
        timer = setInterval(() => {
            if (duration.value > 0) {
                duration.value--
                if (duration.value <= 30) {
                    showTip.value = true
                }
            }
        }, 1000)

        await initAudioAndWS()
        hasInterviewed.value = await interviewStore.checkInterviewHistory()

        // 监听音频播放状态
        const audio = document.getElementById('ttsPlayer')
        audio.addEventListener('play', () => {
            aiSpeaking.value = true
            isAudioPlaying.value = true
            isUserSpeaking.value = false
        })
        audio.addEventListener('ended', () => {
            aiSpeaking.value = false
            isAudioPlaying.value = false
            isUserSpeaking.value = false
        })
        audio.addEventListener('pause', () => {
            aiSpeaking.value = false
            isAudioPlaying.value = false
            isUserSpeaking.value = false
        })
    })

    onBeforeUnmount(() => {
        cleanup()
    })
</script>

<style lang="scss" scoped>
    .interview-voice {
        min-height: 100vh;
        background: linear-gradient(180deg, #000B24 0%, #000B24 100%);
        display: flex;
        flex-direction: column;
        align-items: center;
        padding: 20px;
        color: #fff;

        .top-tip {
            width: 100%;
            position: fixed;
            top: 10%;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(255, 77, 79, 0.1);
            color: #ff4d4f;
            border-radius: 20px;
            display: flex;
            align-items: center;
            font-size: 14px;

            .van-notice-bar {
                width: 100%;
            }

            .van-icon {
                margin-right: 4px;
            }
        }

        .interview-timer {
            font-size: 18px;
            margin: 10px 0 60px;
            opacity: 0.8;
        }

        .ai-avatar {
            margin-bottom: 20px;
            position: relative;
            display: flex;
            flex-direction: column;
            align-items: center;

            .avatar-bg {
                width: 120px;
                height: 120px;
                border-radius: 50%;
                background: rgba(255, 228, 186, 1);
                margin-bottom: 30px;
            }

            img {
                width: 100%;
                height: 100%;
                border-radius: 50%;
            }

            .voice-status {
                text-align: center;
                font-size: 16px;
                min-height: 24px;

                .wave-animation {
                    display: flex;
                    align-items: center;
                    gap: 4px;
                    height: 20px;

                    .wave-bar {
                        width: 8px;
                        height: 100%;
                        background-color: rgba(255, 255, 255, 1);
                        animation: waveAnim 1s ease-in-out infinite;
                        transform-origin: 50% 50%;

                        @for $i from 1 through 4 {
                            &:nth-child(#{$i}) {
                                animation-delay: $i * 0.1s;
                            }
                        }
                    }
                }
            }
        }

        .voice-tip {
            margin-top: 20px;
            display: flex;
            align-items: center;
            color: rgba(255, 255, 255, 0.6);
            font-size: 14px;

            .van-icon {
                margin-right: 4px;
            }
        }

        .control-bar {
            position: fixed;
            bottom: 40px;
            left: 0;
            right: 0;
            display: flex;
            justify-content: space-around;
            align-items: center;
            padding: 0 20px;

            .control-btn {
                display: flex;
                flex-direction: column;
                align-items: center;
                opacity: 0.8;
                transition: all 0.3s;

                &.active {
                    color: #8a2be2;
                }

                &.hang-up {
                    color: #ff4d4f;
                }

                img {
                    width: 80px;
                    height: 80px;
                    margin-bottom: 8px;
                }

                span {
                    font-size: 16px;
                }
            }

            .interrupt-btn {
                display: flex;
                flex-direction: column;
                align-items: center;
                background: rgba(255, 255, 255, 0.1);
                padding: 12px 24px;
                border-radius: 24px;
                transition: all 0.3s;

                &.disabled {
                    opacity: 0.5;
                    pointer-events: none;
                }

                .van-icon {
                    font-size: 28px;
                    margin-bottom: 8px;
                }

                span {
                    font-size: 14px;
                }
            }
        }
    }

    @keyframes waveAnim {

        0%,
        100% {
            transform: scaleY(0.5);
        }

        50% {
            transform: scaleY(1);
        }
    }

    // 弹窗样式覆盖
    :deep(.van-dialog) {
        .van-dialog__message {
            padding: 24px 16px;
            line-height: 1.6;
        }

        .van-button {
            height: 40px;
            font-size: 16px;
        }
    }
</style>